<?php


namespace backend\models\c2\entity;


use common\helpers\CodeGenerator;
use common\models\c2\entity\Product;
use common\models\c2\entity\ProductCombination;
use common\models\c2\entity\ProductionConsumption;
use common\models\c2\entity\ProductionScheduleItem;
use common\models\c2\entity\ProductPackage;
use common\models\c2\statics\ProductionCommitNoteState;
use common\models\c2\statics\ProductionScheduleState;
use common\models\c2\statics\ProductionScheduleType;
use cza\base\models\statics\EntityModelStatus;
use Yii;
use yii\helpers\ArrayHelper;
use yii\validators\RequiredValidator;

class ProductionSchedule extends \common\models\c2\entity\ProductionSchedule
{
    public $items;

    public function rules()
    {
        return ArrayHelper::merge(parent::rules(), [
            [['items'], 'safe'],
            [['items'], 'validateItems'],
        ]); // TODO: Change the autogenerated stub
    }

    public function loadDefaultValues($skipIfSet = true)
    {
        parent::loadDefaultValues($skipIfSet); // TODO: Change the autogenerated stub
        if ($this->isNewRecord) {
            $this->code = CodeGenerator::getCodeByDate($this, 'PS');
            $this->type = ProductionScheduleType::PRODUCT;
        }
    }

    public function validateItems($attribute)
    {
        $items = $this->$attribute;

        foreach ($items as $index => $row) {
            $requiredValidator = new RequiredValidator();
            $error = null;
            $requiredValidator->validate($row['product_id'], $error);
            $requiredValidator->validate($row['combination_id'], $error);
            $requiredValidator->validate($row['package_id'], $error);
            if (!empty($error)) {
                $key = $attribute . '[' . $index . '][product_id]';
                // $this->addError($key, Yii::t('app.c2', 'Product/Combination/Package not be null.'));
                $this->addError($key, Yii::t('app.c2', '{attribute} can not be empty!', ['attribute' => Yii::t('app.c2', 'Product')]));
            }
            if (!empty($error)) {
                $key = $attribute . '[' . $index . '][combination_id]';
                // $this->addError($key, Yii::t('app.c2', 'Product/Combination/Package not be null.'));
                $this->addError($key, Yii::t('app.c2', '{attribute} can not be empty!', ['attribute' => Yii::t('app.c2', 'Product Combination')]));
            }
            if (!empty($error)) {
                $key = $attribute . '[' . $index . '][package_id]';
                // $this->addError($key, Yii::t('app.c2', 'Product/Combination/Package not be null.'));
                $this->addError($key, Yii::t('app.c2', '{attribute} can not be empty!', ['attribute' => Yii::t('app.c2', 'Product Package')]));
            }
        }
    }

    public function setStateToCalculation()
    {
        $db = Yii::$app->db->beginTransaction();
        foreach ($this->scheduleItems as $scheduleItem) {
            // get product combination items
            $productCombination = $scheduleItem->productCombination;
            if (!is_null($productCombination)) {
                foreach ($productCombination->combinationItems as $combinationItem) {
                    // get product model
                    $product = $combinationItem->product;
                    if (!is_null($product)) {
                        $attributes = [
                            'schedule_id' => $this->id,
                            'schedule_item_id' => $scheduleItem->id,
                            'need_product_id' => $product->id,
                            'need_product_sku' => $product->sku,
                            'need_product_name' => $product->name,
                            'need_product_label' => $product->label,
                            'need_product_value' => $product->value,
                            'need_number' => $combinationItem->need_number,
                            'need_sum' => $combinationItem->need_number * $scheduleItem->production_sum,
                            'send_sum' => 0,
                            'memo' => "",
                        ];
                        $consumptionModel = new ProductionConsumption();
                        $consumptionModel->setAttributes($attributes);
                        $consumptionModel->save();
                    }
                }
            }

            // get product package items
            $productPackage = $scheduleItem->productPackage;
            if (!is_null($productPackage)) {
                foreach ($productPackage->packageItems as $packageItem) {
                    // get product model
                    $product = $packageItem->product;
                    if (!is_null($product)) {
                        $attributes = [
                            'schedule_id' => $this->id,
                            'schedule_item_id' => $scheduleItem->id,
                            'need_product_id' => $product->id,
                            'need_product_sku' => $product->sku,
                            'need_product_name' => $product->name,
                            'need_product_label' => $product->label,
                            'need_product_value' => $product->value,
                            'need_number' => $packageItem->need_number,
                            'need_sum' => $packageItem->need_number * $scheduleItem->pieces,
                            'send_sum' => 0,
                            'memo' => "",
                        ];
                        $consumptionModel = new ProductionConsumption();
                        $consumptionModel->setAttributes($attributes);
                        $consumptionModel->save();
                    }
                }
            }
        }
        $this->updateAttributes([
            'state' => ProductionScheduleState::CALCULATION
        ]);
        $db->commit();
    }

    public function setStateToCommit()
    {
        $this->updateAttributes([
            'state' => ProductionScheduleState::COMMIT
        ]);
    }

    public function beforeDelete()
    {
        foreach ($this->getScheduleItems()->all() as $item) {
            $item->delete();
        }
        foreach ($this->getScheduleItemConsumption()->all() as $item) {
            $item->delete();
        }
        return parent::beforeDelete(); // TODO: Change the autogenerated stub
    }

    public function afterSave($insert, $changedAttributes)
    {
        parent::afterSave($insert, $changedAttributes); // TODO: Change the autogenerated stub
        if (!empty($this->items)) {
            foreach ($this->items as $item) {
                $product = Product::findOne($item['product_id']);
                $combination = ProductCombination::findOne($item['combination_id']);
                $package = ProductPackage::findOne($item['package_id']);
                $pieces = isset($item['pieces']) ? $item['pieces'] : 0;
                $production_sum = $item['production_sum'] == '' ? $package->product_capacity * $pieces : $item['production_sum'];
                $attributes = [
                    'product_id' => !is_null($product) ? $product->id : 0,
                    'product_name' => !is_null($product) ? $product->name : '',
                    'product_sku' => !is_null($product) ? $product->sku : '',
                    'product_label' => !is_null($product) ? $product->label : '',
                    'product_value' => !is_null($product) ? $product->value : '',
                    'combination_id' => !is_null($combination) ? $combination->id : 0,
                    'combination_name' => !is_null($combination) ? $combination->name : '',
                    'package_id' => !is_null($package) ? $package->id : 0,
                    'package_name' => !is_null($package) ? $package->name : '',
                    'measure_id' => isset($item['measure_id']) ? $item['measure_id'] : 0,
                    'pieces' => $pieces,
                    // 'production_sum' => isset($item['production_sum']) ? $item['production_sum'] : 0,
                    'production_sum' => $production_sum,
                    'memo' => isset($item['memo']) ? $item['memo'] : '',
                    'position' => isset($item['position']) ? $item['position'] : 0,
                    'state' => 0,
                    'status' => EntityModelStatus::STATUS_INACTIVE
                ];
                if (isset($item['id']) && $item['id'] == '') {
                    $itemModel = new ProductionScheduleItem();
                    $itemModel->setAttributes($attributes);
                    $itemModel->link('owner', $this);
                } elseif (isset($item['id'])) {
                    $itemModel = ProductionScheduleItem::findOne($item['id']);
                    if (!is_null($itemModel)) {
                        $itemModel->updateAttributes($attributes);
                    }
                }
            }
        }
    }

    public function loadItems()
    {
        $this->items = $this->getScheduleItems()->all();
    }

    public function setStateToFinish()
    {
        // $items = $this->getScheduleItems()->all();
        // if (!empty($items)) {
        //     foreach ($items as $item) {
        //         $product = $item->product;
        //         $product->stock += $item->production_sum;
        //         $product->save();
        //     }
        // }
        $this->updateAttributes(['state' => ProductionScheduleState::FINISH]);
    }

}